//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS CostOptimizationHub service.
///
/// You can use the Cost Optimization Hub API to programmatically identify, filter, aggregate, and quantify savings for your cost optimization recommendations across multiple Amazon Web Services Regions and Amazon Web Services accounts in your organization. The Cost Optimization Hub API provides the following endpoint:    https://cost-optimization-hub.us-east-1.amazonaws.com
public struct CostOptimizationHub: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the CostOptimizationHub client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            amzTarget: "CostOptimizationHubService",
            serviceName: "CostOptimizationHub",
            serviceIdentifier: "cost-optimization-hub",
            serviceProtocol: .json(version: "1.0"),
            apiVersion: "2022-07-26",
            endpoint: endpoint,
            serviceEndpoints: Self.serviceEndpoints,
            errorType: CostOptimizationHubErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }


    /// custom endpoints for regions
    static var serviceEndpoints: [String: String] {[
        "eu-isoe-west-1": "cost-optimization-hub.eu-isoe-west-1.cloud.adc-e.uk",
        "us-east-1": "cost-optimization-hub.us-east-1.amazonaws.com",
        "us-isof-south-1": "cost-optimization-hub.us-isof-south-1.csp.hci.ic.gov"
    ]}



    // MARK: API Calls

    /// Returns a set of preferences for an account in order to add account-specific preferences into the service. These preferences impact how the savings associated with recommendations are presented—estimated savings after discounts or estimated savings before discounts, for example.
    @Sendable
    @inlinable
    public func getPreferences(_ input: GetPreferencesRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetPreferencesResponse {
        try await self.client.execute(
            operation: "GetPreferences", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a set of preferences for an account in order to add account-specific preferences into the service. These preferences impact how the savings associated with recommendations are presented—estimated savings after discounts or estimated savings before discounts, for example.
    ///
    /// Parameters:
    ///   - logger: Logger use during operation
    @inlinable
    public func getPreferences(
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetPreferencesResponse {
        let input = GetPreferencesRequest(
        )
        return try await self.getPreferences(input, logger: logger)
    }

    /// Returns both the current and recommended resource configuration and the estimated cost impact for a recommendation. The recommendationId is only valid for up to a maximum of 24 hours as recommendations are refreshed daily. To retrieve the recommendationId, use the ListRecommendations API.
    @Sendable
    @inlinable
    public func getRecommendation(_ input: GetRecommendationRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> GetRecommendationResponse {
        try await self.client.execute(
            operation: "GetRecommendation", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns both the current and recommended resource configuration and the estimated cost impact for a recommendation. The recommendationId is only valid for up to a maximum of 24 hours as recommendations are refreshed daily. To retrieve the recommendationId, use the ListRecommendations API.
    ///
    /// Parameters:
    ///   - recommendationId: The ID for the recommendation.
    ///   - logger: Logger use during operation
    @inlinable
    public func getRecommendation(
        recommendationId: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetRecommendationResponse {
        let input = GetRecommendationRequest(
            recommendationId: recommendationId
        )
        return try await self.getRecommendation(input, logger: logger)
    }

    /// Retrieves the enrollment status for an account. It can also return the list of accounts that are enrolled under the organization.
    @Sendable
    @inlinable
    public func listEnrollmentStatuses(_ input: ListEnrollmentStatusesRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListEnrollmentStatusesResponse {
        try await self.client.execute(
            operation: "ListEnrollmentStatuses", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Retrieves the enrollment status for an account. It can also return the list of accounts that are enrolled under the organization.
    ///
    /// Parameters:
    ///   - accountId: The account ID of a member account in the organization.
    ///   - includeOrganizationInfo: Indicates whether to return the enrollment status for the organization.
    ///   - maxResults: The maximum number of objects that are returned for the request.
    ///   - nextToken: The token to retrieve the next set of results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listEnrollmentStatuses(
        accountId: String? = nil,
        includeOrganizationInfo: Bool? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListEnrollmentStatusesResponse {
        let input = ListEnrollmentStatusesRequest(
            accountId: accountId, 
            includeOrganizationInfo: includeOrganizationInfo, 
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listEnrollmentStatuses(input, logger: logger)
    }

    /// Returns a concise representation of savings estimates for resources. Also returns de-duped savings across different types of recommendations.  The following filters are not supported for this API: recommendationIds, resourceArns, and resourceIds.
    @Sendable
    @inlinable
    public func listRecommendationSummaries(_ input: ListRecommendationSummariesRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListRecommendationSummariesResponse {
        try await self.client.execute(
            operation: "ListRecommendationSummaries", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a concise representation of savings estimates for resources. Also returns de-duped savings across different types of recommendations.  The following filters are not supported for this API: recommendationIds, resourceArns, and resourceIds.
    ///
    /// Parameters:
    ///   - filter: 
    ///   - groupBy: The grouping of recommendations by a dimension.
    ///   - maxResults: The maximum number of recommendations to be returned for the request.
    ///   - metrics: Additional metrics to be returned for the request. The only valid value is savingsPercentage.
    ///   - nextToken: The token to retrieve the next set of results.
    ///   - logger: Logger use during operation
    @inlinable
    public func listRecommendationSummaries(
        filter: Filter? = nil,
        groupBy: String,
        maxResults: Int? = nil,
        metrics: [SummaryMetrics]? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListRecommendationSummariesResponse {
        let input = ListRecommendationSummariesRequest(
            filter: filter, 
            groupBy: groupBy, 
            maxResults: maxResults, 
            metrics: metrics, 
            nextToken: nextToken
        )
        return try await self.listRecommendationSummaries(input, logger: logger)
    }

    /// Returns a list of recommendations.
    @Sendable
    @inlinable
    public func listRecommendations(_ input: ListRecommendationsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListRecommendationsResponse {
        try await self.client.execute(
            operation: "ListRecommendations", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Returns a list of recommendations.
    ///
    /// Parameters:
    ///   - filter: The constraints that you want all returned recommendations to match.
    ///   - includeAllRecommendations: List of all recommendations for a resource, or a single recommendation if de-duped by resourceId.
    ///   - maxResults: The maximum number of recommendations that are returned for the request.
    ///   - nextToken: The token to retrieve the next set of results.
    ///   - orderBy: The ordering of recommendations by a dimension.
    ///   - logger: Logger use during operation
    @inlinable
    public func listRecommendations(
        filter: Filter? = nil,
        includeAllRecommendations: Bool? = nil,
        maxResults: Int? = nil,
        nextToken: String? = nil,
        orderBy: OrderBy? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListRecommendationsResponse {
        let input = ListRecommendationsRequest(
            filter: filter, 
            includeAllRecommendations: includeAllRecommendations, 
            maxResults: maxResults, 
            nextToken: nextToken, 
            orderBy: orderBy
        )
        return try await self.listRecommendations(input, logger: logger)
    }

    /// Updates the enrollment (opt in and opt out) status of an account to the Cost Optimization Hub service. If the account is a management account or delegated administrator of an organization, this action can also be used to enroll member accounts of the organization. You must have the appropriate permissions to opt in to Cost Optimization Hub and to view its recommendations. When you opt in, Cost Optimization Hub automatically creates a service-linked role in your account to access its data.
    @Sendable
    @inlinable
    public func updateEnrollmentStatus(_ input: UpdateEnrollmentStatusRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UpdateEnrollmentStatusResponse {
        try await self.client.execute(
            operation: "UpdateEnrollmentStatus", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Updates the enrollment (opt in and opt out) status of an account to the Cost Optimization Hub service. If the account is a management account or delegated administrator of an organization, this action can also be used to enroll member accounts of the organization. You must have the appropriate permissions to opt in to Cost Optimization Hub and to view its recommendations. When you opt in, Cost Optimization Hub automatically creates a service-linked role in your account to access its data.
    ///
    /// Parameters:
    ///   - includeMemberAccounts: Indicates whether to enroll member accounts of the organization if the account is the management account or delegated administrator.
    ///   - status: Sets the account status.
    ///   - logger: Logger use during operation
    @inlinable
    public func updateEnrollmentStatus(
        includeMemberAccounts: Bool? = nil,
        status: EnrollmentStatus,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UpdateEnrollmentStatusResponse {
        let input = UpdateEnrollmentStatusRequest(
            includeMemberAccounts: includeMemberAccounts, 
            status: status
        )
        return try await self.updateEnrollmentStatus(input, logger: logger)
    }

    /// Updates a set of preferences for an account in order to add account-specific preferences into the service. These preferences impact how the savings associated with recommendations are presented.
    @Sendable
    @inlinable
    public func updatePreferences(_ input: UpdatePreferencesRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UpdatePreferencesResponse {
        try await self.client.execute(
            operation: "UpdatePreferences", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Updates a set of preferences for an account in order to add account-specific preferences into the service. These preferences impact how the savings associated with recommendations are presented.
    ///
    /// Parameters:
    ///   - memberAccountDiscountVisibility: Sets the "member account discount visibility" preference.
    ///   - preferredCommitment: Sets the preferences for how Reserved Instances and Savings Plans cost-saving opportunities are prioritized in terms of payment option and term length.
    ///   - savingsEstimationMode: Sets the "savings estimation mode" preference.
    ///   - logger: Logger use during operation
    @inlinable
    public func updatePreferences(
        memberAccountDiscountVisibility: MemberAccountDiscountVisibility? = nil,
        preferredCommitment: PreferredCommitment? = nil,
        savingsEstimationMode: SavingsEstimationMode? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UpdatePreferencesResponse {
        let input = UpdatePreferencesRequest(
            memberAccountDiscountVisibility: memberAccountDiscountVisibility, 
            preferredCommitment: preferredCommitment, 
            savingsEstimationMode: savingsEstimationMode
        )
        return try await self.updatePreferences(input, logger: logger)
    }
}

extension CostOptimizationHub {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: CostOptimizationHub, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension CostOptimizationHub {
    /// Return PaginatorSequence for operation ``listEnrollmentStatuses(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listEnrollmentStatusesPaginator(
        _ input: ListEnrollmentStatusesRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListEnrollmentStatusesRequest, ListEnrollmentStatusesResponse> {
        return .init(
            input: input,
            command: self.listEnrollmentStatuses,
            inputKey: \ListEnrollmentStatusesRequest.nextToken,
            outputKey: \ListEnrollmentStatusesResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listEnrollmentStatuses(_:logger:)``.
    ///
    /// - Parameters:
    ///   - accountId: The account ID of a member account in the organization.
    ///   - includeOrganizationInfo: Indicates whether to return the enrollment status for the organization.
    ///   - maxResults: The maximum number of objects that are returned for the request.
    ///   - logger: Logger used for logging
    @inlinable
    public func listEnrollmentStatusesPaginator(
        accountId: String? = nil,
        includeOrganizationInfo: Bool? = nil,
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListEnrollmentStatusesRequest, ListEnrollmentStatusesResponse> {
        let input = ListEnrollmentStatusesRequest(
            accountId: accountId, 
            includeOrganizationInfo: includeOrganizationInfo, 
            maxResults: maxResults
        )
        return self.listEnrollmentStatusesPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listRecommendationSummaries(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listRecommendationSummariesPaginator(
        _ input: ListRecommendationSummariesRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListRecommendationSummariesRequest, ListRecommendationSummariesResponse> {
        return .init(
            input: input,
            command: self.listRecommendationSummaries,
            inputKey: \ListRecommendationSummariesRequest.nextToken,
            outputKey: \ListRecommendationSummariesResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listRecommendationSummaries(_:logger:)``.
    ///
    /// - Parameters:
    ///   - filter: 
    ///   - groupBy: The grouping of recommendations by a dimension.
    ///   - maxResults: The maximum number of recommendations to be returned for the request.
    ///   - metrics: Additional metrics to be returned for the request. The only valid value is savingsPercentage.
    ///   - logger: Logger used for logging
    @inlinable
    public func listRecommendationSummariesPaginator(
        filter: Filter? = nil,
        groupBy: String,
        maxResults: Int? = nil,
        metrics: [SummaryMetrics]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListRecommendationSummariesRequest, ListRecommendationSummariesResponse> {
        let input = ListRecommendationSummariesRequest(
            filter: filter, 
            groupBy: groupBy, 
            maxResults: maxResults, 
            metrics: metrics
        )
        return self.listRecommendationSummariesPaginator(input, logger: logger)
    }

    /// Return PaginatorSequence for operation ``listRecommendations(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listRecommendationsPaginator(
        _ input: ListRecommendationsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListRecommendationsRequest, ListRecommendationsResponse> {
        return .init(
            input: input,
            command: self.listRecommendations,
            inputKey: \ListRecommendationsRequest.nextToken,
            outputKey: \ListRecommendationsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listRecommendations(_:logger:)``.
    ///
    /// - Parameters:
    ///   - filter: The constraints that you want all returned recommendations to match.
    ///   - includeAllRecommendations: List of all recommendations for a resource, or a single recommendation if de-duped by resourceId.
    ///   - maxResults: The maximum number of recommendations that are returned for the request.
    ///   - orderBy: The ordering of recommendations by a dimension.
    ///   - logger: Logger used for logging
    @inlinable
    public func listRecommendationsPaginator(
        filter: Filter? = nil,
        includeAllRecommendations: Bool? = nil,
        maxResults: Int? = nil,
        orderBy: OrderBy? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListRecommendationsRequest, ListRecommendationsResponse> {
        let input = ListRecommendationsRequest(
            filter: filter, 
            includeAllRecommendations: includeAllRecommendations, 
            maxResults: maxResults, 
            orderBy: orderBy
        )
        return self.listRecommendationsPaginator(input, logger: logger)
    }
}

extension CostOptimizationHub.ListEnrollmentStatusesRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> CostOptimizationHub.ListEnrollmentStatusesRequest {
        return .init(
            accountId: self.accountId,
            includeOrganizationInfo: self.includeOrganizationInfo,
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

extension CostOptimizationHub.ListRecommendationSummariesRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> CostOptimizationHub.ListRecommendationSummariesRequest {
        return .init(
            filter: self.filter,
            groupBy: self.groupBy,
            maxResults: self.maxResults,
            metrics: self.metrics,
            nextToken: token
        )
    }
}

extension CostOptimizationHub.ListRecommendationsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> CostOptimizationHub.ListRecommendationsRequest {
        return .init(
            filter: self.filter,
            includeAllRecommendations: self.includeAllRecommendations,
            maxResults: self.maxResults,
            nextToken: token,
            orderBy: self.orderBy
        )
    }
}
